using UnityEngine;
using System.Collections;
using System.Collections.Generic;


public delegate void InitStateFunc();
public delegate void UpdateStateFunc();


public class BM_FSM
{
	public class StateInfo
	{
		public int				m_iStateId = -1;
		public string			m_strStateName = "";
		public InitStateFunc	m_rInitStateFunc = null;
		public UpdateStateFunc	m_rUpdateStateFunc = null;
		
		public StateInfo(int iStateId, string strStateName, InitStateFunc rInitStateFunc, UpdateStateFunc rUpdateStateFunc)
		{
			m_iStateId = iStateId;
			if(Debug.isDebugBuild && m_iStateId < 0)
				Debug.DebugBreak();
						
			m_strStateName = strStateName;
			if(Debug.isDebugBuild && m_strStateName == "")
				Debug.DebugBreak();
			
			m_rInitStateFunc = rInitStateFunc;
			m_rUpdateStateFunc = rUpdateStateFunc;
		}
	}
	
	#region Members
	
	private bool							m_bDebugPrint = false;
	private Dictionary<int, StateInfo>		m_dictStates = new Dictionary<int, StateInfo>();
	private StateInfo						m_rCurrentState = null;
	private StateInfo						m_rNextState = null;
	
	#endregion
	
	
	#region Properties
	
	public int NextState
	{
		set
		{
			if(Debug.isDebugBuild && m_rNextState != null)
				Debug.LogWarning("SV_FSM.NextState() -> E' stato richiesto piu' di un cambio di stato durante lo stesso frame... PreviousState: " + m_rNextState.m_iStateId);
			
			
			StateInfo rTempState = null;
			if(m_dictStates.TryGetValue(value, out rTempState))
				m_rNextState = rTempState;
			else
			{
				if(Debug.isDebugBuild)
				{
					Debug.LogError("SV_FSM.NextState() -> Invalid State!");
					Debug.DebugBreak();
				}
			}
		}
	}
	
	public int CurrentState
	{
		get
		{
			int iRVal = -1;
			
			if(m_rCurrentState != null)
				iRVal = m_rCurrentState.m_iStateId;
			
			return iRVal;
		}
	}
	
	public bool DebugPrint
	{
		get { return m_bDebugPrint; }
		set { m_bDebugPrint = value; }
	}
	
	public string CurrentStateName
	{
		get
		{
			string strRVal = "";
			
			if(m_rCurrentState != null)
				strRVal = m_rCurrentState.m_strStateName;
			
			return strRVal;
		}
	}

	#endregion
	
	
	
	public bool AddState(StateInfo rStateInfo)
	{
		bool bRVal = false;
		
		if(!m_dictStates.ContainsKey(rStateInfo.m_iStateId))
		{
			m_dictStates.Add(rStateInfo.m_iStateId, rStateInfo);
			bRVal = true;
		}
		else if(Debug.isDebugBuild)
			Debug.LogError("SV_FSM.AddState() -> State already added...");
		
		return bRVal;
	}	
	
	public void UpdateFSM()
	{
		if(m_rNextState != null)
		{
			m_rCurrentState = m_rNextState;
			m_rNextState  = null;
			
			if(m_bDebugPrint)
				Debug.Log("SV_FSM.UpdateFSM() -> Entering in state " + m_rCurrentState.m_strStateName);
			
			if(m_rCurrentState.m_rInitStateFunc != null)
				m_rCurrentState.m_rInitStateFunc();
		}
		
		if(m_rCurrentState != null && m_rCurrentState.m_rUpdateStateFunc != null)
			m_rCurrentState.m_rUpdateStateFunc();
	}
}
